/**
 * 
 */
package mblog.core.persist.dao.impl;

import java.util.List;

import mblog.core.persist.dao.CommentDao;
import mtons.modules.persist.impl.DaoImpl;
import mtons.modules.pojos.Page;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.faxsun.core.persist.entity.CommentPO;
import com.faxsun.core.pojos.enums.CommentType;

/**
 * @author langhsu
 * @author songdragon 2015-04-29 14:54 添加评论类型
 */
public class CommentDaoImpl extends DaoImpl<CommentPO> implements CommentDao {
	private static final long serialVersionUID = 1023552695901348149L;

	public CommentDaoImpl() {
		super(CommentPO.class);
	}

	@Override
	public List<CommentPO> paging(Page page, long toId, int type, int status) {
		PagingQuery<CommentPO> q = pagingQuery(page);
		if (toId >= 0) {
			q.add(Restrictions.eq("toId", toId));
		}
		if (type >= 0) {
			q.add(Restrictions.eq("type", type));
		}
		if (status >= 0) {
			q.add(Restrictions.eq("status", status));
		}
		q.desc("created");
		return q.list();
	}

	/**
	 * @author songdragon
	 * @Date 2015-04-14 15:32
	 */
	@Override
	public List<CommentPO> retrieveNewest(Page page) {
		PagingQuery<CommentPO> q = pagingQuery(page);
		q.add(Restrictions.eq("status", 1));
        q.add(Restrictions.eq("type", CommentType.POST.getIntValue()));//对文章的评论
        q.add(Restrictions.eq("type", CommentType.PRODUCT.getIntValue()));//对产品的评论
		q.desc("created");
		return q.list();
	}

	/**
	 * 将评论状态标记为删除，并减少对应文章或产品的评论数
	 */
	@Override
	public boolean delete(long id) {

		CommentPO comment = this.get(id);
		if (comment != null) {
			// FIXME: use constants instead of magic number
			comment.setStatus(2);
			this.save(comment);
			return true;
		}
		return false;
	}

    @Override
    public List<CommentPO> pagingInbox(Page page, long userId, int status) {
        PagingQuery<CommentPO> q = pagingQuery(page);
        if (userId >= 0) {
            q.add(Restrictions.or(Restrictions.eq("toId", userId), Restrictions.eq("author.id", userId)));
        }
        q.add(Restrictions.eq("type", CommentType.INBOX.getIntValue()));
        if (status >= 0) {
            q.add(Restrictions.eq("status", status));
        }
        q.desc("created");
        return q.list();
    }

    @Override
    public List<CommentPO> getCommentsFrom(long toId, long startId, long endId, int size, List<Integer> types, int status, List<Long> blacklistAuthors) {
        /*
        TopQuery<CommentPO> q = topQuery(size);
        
        q.add(Restrictions.eq("toId", toId));
        
        if(startId > 0){
            q.add(Restrictions.gt("id", startId));            
            q.asc("id");           
        }
        if(endId > 0){
            q.add(Restrictions.lt("id", endId));           
            q.desc("id");
        }
        
        q.add(Restrictions.in("type", types));
        
        q.add(Restrictions.eq("status", status));
        
        // filter out comment from blacklistAuthors
        if(blacklistAuthors != null && blacklistAuthors.size() > 0){
           for(Long id : blacklistAuthors){
               q.add(Restrictions.ne("author.id", id));
           }            
        }  
        */
        
        Query q = null;
        long myId = -1;
        List<Long> bkids = blacklistAuthors;
        /*
        if(startId > 0){
           if(blacklistAuthors != null && blacklistAuthors.size() > 0){
              q = super.createQuery(
                       "SELECT cmt FROM CommentPO cmt, LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.id>:myId AND cmt.type IN (:types) AND cmt.status=:status AND cmt.toId=lm.id AND cmt.author.id NOT IN (:bkids) ORDER BY cmt.id ASC");

              q.setParameterList("bkids", bkids); 
           }else{
              q = super.createQuery(
                        "SELECT cmt FROM CommentPO cmt, LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.id>:myId AND cmt.type IN (:types) AND cmt.status=:status AND cmt.toId=lm.id ORDER BY cmt.id ASC");

           }
           myId = startId;
        }else{
           if(blacklistAuthors != null && blacklistAuthors.size() > 0){
               q = super.createQuery(
                       "SELECT cmt FROM CommentPO cmt, LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.id<:myId AND cmt.type IN (:types) AND cmt.status=:status AND cmt.toId=lm.id AND cmt.author.id NOT IN (:bkids) ORDER BY cmt.id DESC");

               q.setParameterList("bkids", bkids); 
           }else{
               q = super.createQuery(
                       "SELECT cmt FROM CommentPO cmt, LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.id<:myId AND cmt.type IN (:types) AND cmt.status=:status AND cmt.toId=lm.id ORDER BY cmt.id DESC");
               
           }
           myId = endId;
        }
        */
        

        if(startId > 0){
           if(blacklistAuthors != null && blacklistAuthors.size() > 0){
              q = super.createQuery(
                       "SELECT cmt FROM CommentPO cmt WHERE cmt.id>:myId AND cmt.status=:status AND cmt.author.id NOT IN (:bkids) AND ( (cmt.type = 3 AND cmt.toId=:toId) OR (cmt.type = 4 AND cmt.toId = (SELECT lm.id FROM LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.toId=lm.id) ) ) ORDER BY cmt.id ASC");

              q.setParameterList("bkids", bkids); 
           }else{
              q = super.createQuery(
                       "SELECT cmt FROM CommentPO cmt WHERE cmt.id>:myId AND cmt.status=:status AND ( (cmt.type = 3 AND cmt.toId=:toId) OR (cmt.type = 4 AND cmt.toId = (SELECT lm.id FROM LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.toId=lm.id) ) ) ORDER BY cmt.id ASC");

           }
           myId = startId;
        }else{
           if(blacklistAuthors != null && blacklistAuthors.size() > 0){
               q = super.createQuery(
                        "SELECT cmt FROM CommentPO cmt WHERE cmt.id<:myId AND cmt.status=:status AND cmt.author.id NOT IN (:bkids) AND ( (cmt.type = 3 AND cmt.toId=:toId) OR (cmt.type = 4 AND cmt.toId = (SELECT lm.id FROM LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.toId=lm.id) ) ) ORDER BY cmt.id DESC");

               q.setParameterList("bkids", bkids); 
           }else{
               q = super.createQuery(
                        "SELECT cmt FROM CommentPO cmt WHERE cmt.id<:myId AND cmt.status=:status AND ( (cmt.type = 3 AND cmt.toId=:toId) OR (cmt.type = 4 AND cmt.toId = (SELECT lm.id FROM LiveMsgPO lm WHERE lm.channel.id=:toId AND cmt.toId=lm.id) ) ) ORDER BY cmt.id DESC");

           }
           myId = endId;
        }
        
        q.setParameter("toId", toId);
        q.setParameter("myId", myId);
        q.setParameter("status", status);
        //q.setParameterList("types", types);
        q.setMaxResults(size);
        @SuppressWarnings("unchecked")
		List<CommentPO> list = q.list();

        return list;
    }

    @Override
    public long getMaxCommentIdFrom(long toId, int type, int status, List<Long> blacklistAuthors) {
        Criteria maxC = this.createCriteria();

        maxC.add(Restrictions.eq("toId", toId));
        maxC.add(Restrictions.eq("type", type));
        maxC.add(Restrictions.eq("status", status));
        
        // filter out comment from blacklistAuthors
        if(blacklistAuthors != null && blacklistAuthors.size() > 0){
           for(Long id : blacklistAuthors){
               maxC.add(Restrictions.ne("author.id", id));
           }            
        }

        maxC.setProjection(Projections.max("id"));
        
        Long max = (Long) maxC.list().get(0);        
        return max == null? 0 : max.longValue();
    }

    @Override
    public int count(Long toId, int type) {
        Criteria count = this.createCriteria();
        count.add(Restrictions.eq("toId", toId));
        count.add(Restrictions.eq("type", type));

        count.setProjection(Projections.count("id"));
        Long total = (Long) count.list().get(0);
        return total.intValue();
    }
}
